package com.biannuo.szk.gateway.predicate;

import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

/**
 * 自定义路由断言工厂
 * 只允许查询id为minId- maxId之间的用户
 *
 * @author szk
 */
@Component
public class UserRoutePredicateFactory extends AbstractRoutePredicateFactory<UserRoutePredicateFactory.Config> {
    /**
     * 对象属性
     */
    public static final String[] KEY_ARRAY = {"minId", "maxId"};

    public UserRoutePredicateFactory() { // 构造函数
        super(Config.class);
    }

    /**
     * 读取配置文件中的值，赋值到Config对象属性值
     *
     * @return
     */
    @Override
    public List<String> shortcutFieldOrder() {
        //顺序注意跟配置一致
        return Arrays.asList(KEY_ARRAY);
    }

    /**
     * 断言逻辑
     *
     * @param config
     * @return
     */
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new GatewayPredicate() {
            @Override
            public boolean test(ServerWebExchange exchange) {
                //得到id参数的值
                String id = exchange.getRequest().getQueryParams().getFirst("id");
                if (null != id) {
                    int numberId = Integer.parseInt(id);
                    //判断id是否大于最小值 并且 小于最大值
                    if (numberId > config.getMinId() && numberId < config.getMaxId()) {
                        return true;
                    }
                }
                return false;
            }

            @Override
            public String toString() {
                return String.format("minId: %d , maxId %d", config.getMinId(), config.getMaxId());
            }
        };
    }

    /**
     * 配置类，接收配置文件的值
     */
    @Validated
    public static class Config {
        // 最小支持查询的id
        private Integer minId;
        // 最大支持查询的id
        private Integer maxId;

        public void setMinId(Integer minId) {
            this.minId = minId;
        }

        public void setMaxId(Integer maxId) {
            this.maxId = maxId;
        }

        public Integer getMinId() {
            return minId;
        }

        public Integer getMaxId() {
            return maxId;
        }
    }
}
